package com.annotation;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * 通过反射解析注解
 */
public class MapperHandler {

    public static String query(Object filter) {
        StringBuilder sql = new StringBuilder();
        // 1. 通过反射获取Class
        Class c = filter.getClass();

        // 2. 获取table的名字
        boolean tableExists = c.isAnnotationPresent(Table.class);
        if (!tableExists) {
            return null;
        }
        Table tableAnt = (Table) c.getAnnotation(Table.class);
        String tableName = tableAnt.value();
        sql.append("select * from ").append(tableName).append(" where 1=1 ");

        // 3. 遍历所有的字段
        Field[] declaredFields = c.getDeclaredFields();

        // 4. 处理字段对应的sql
        for (Field declaredField: declaredFields) {

            // 4.1 获取注解名
            boolean columnExists = declaredField.isAnnotationPresent(Column.class);
            if (!columnExists) {
                continue;
            }
            Column columnAnnot = declaredField.getAnnotation(Column.class);
            String columnName = columnAnnot.value();

            // 4.2 获取字段的值 (通过类里面的get方法)  fieldName.substring(1); 表示1到末尾
            String fieldName = declaredField.getName();
            String getMethodName = "get" + fieldName.substring(0, 1).toUpperCase() +
                    fieldName.substring(1);

            // 通过反射 + 获取字段方法名 得到字段的值
            Object  fieldValue = null;
            try {
                Method getMethod = c.getMethod(getMethodName);

                // 反射调用
                fieldValue = getMethod.invoke(filter, null);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            // 4.3 拼装sql
            boolean isZero = (fieldValue instanceof Integer && (Integer)fieldValue == 0);
            if (fieldValue == null || isZero) {
                continue;
            }
            sql.append(" and ").append(columnName);
            if (fieldValue instanceof String) {
                if (((String) fieldValue).contains(",")) {
                    String[] fieldValues = ((String) fieldValue).split(",");
                    sql.append(" in (");
                    for (String v: fieldValues) {
                        sql.append("'").append(v).append("'").append(",");
                    }
                    sql.deleteCharAt(sql.length() - 1);
                    sql.append(" )");
                }else {
                    sql.append(" = ").append("'").append(fieldValue).append("'");
                }
            }else if (fieldValue instanceof Integer) {
                sql.append(" = ").append(fieldValue);
            }
        }
        return sql.append(";").toString();
    }
}
